use std::{rc::Rc, cell::RefCell};

use crate::{instructions::base::{Instruction, BytecodeReader}, rtda::Frame};

// 需要两个操作数。第一个操作数是uint16索引，从方法的字节码中获取，通过这个索引可以从当前类的运行时常量池中找到一个类符号引用。第二个操作数是对象引用，从操作数栈中弹出。
#[derive(Debug, Default)]
pub struct INSTANCE_OF {
    index: usize
}

impl Instruction for INSTANCE_OF {
    fn fetch_operands(&mut self, reader: &mut BytecodeReader) {
        self.index = reader.read_u16() as usize;
    }
    
    // 判断对象是否是某个类的实例（或者对象的类是否实现了某个接口）
    fn execute(&mut self, frame: Rc<RefCell<Frame>>) {
        let stack = frame.borrow().get_operand_stack();
        let _ref = stack.borrow_mut().pop_ref();
        if _ref.is_none() {
            stack.borrow_mut().push_int(0);
            return;
        }
        let _ref = _ref.unwrap();

        let cp = frame.borrow().get_method().get_class().get_constant_pool().unwrap();
        let class_ref = cp.get_constant(self.index).unwrap().class_ref();
        let class = class_ref.lock().unwrap().resolved_class();
        if unsafe { &*_ref }.is_instance_of(class) {
            stack.borrow_mut().push_int(1);
        } else {
            stack.borrow_mut().push_int(0);
        }
    }


}
